package cn._2dland.comment
{
	import cn._2dland.comment.easing.EasingBase;
	import cn._2dland.events.CommentEvent;
	import cn._2dland.utils.CommentUtils;
	import cn._2dland.utils.TransitionUtils;
	
	import fl.transitions.Blinds;
	import fl.transitions.Fade;
	import fl.transitions.Iris;
	import fl.transitions.PixelDissolve;
	import fl.transitions.Transition;
	import fl.transitions.TransitionManager;
	import fl.transitions.Wipe;
	import fl.transitions.easing.None;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	[Event(name="effectEnd",type="cn._2dland.events.CommentEvent")]

	public final class CommentMC extends MovieClip
	{
		private var _textField:TextField;

		// 显示和消失效果
		private var _transManager:TransitionManager;
		private var _inEff:Transition = null;
		private var _outEff:Transition = null;

		// 锁定标志
		public var locked:Boolean = false;

		// 效果进行标记
		public var effecting:Boolean = false;

		// 逻辑坐标，用于定位
		public var logicX:Number = 0;
		public var logicY:Number = 0;

		// 运动相关属性
		public var mode:int = 0;
		public var life:Number = 0;
		public var xSpeed:Number = 0;
		public var ySpeed:Number = 0;
		public var x1:Number = NaN;
		public var y1:Number = NaN;
		public var x2:Number = NaN;
		public var y2:Number = NaN;
		public var angle:int = 0;

		/** 缓动函数 */
		public var easing:EasingBase = null;

		public function CommentMC() {
			super();
			visible = false;
		}

		/**
		 * 设置评论内容
		 * @param cmntObj
		 */
		public function setComment(cmntObj:CommentObject):void {
			// 初始化TextField
			_textField = new TextField();
			_textField.autoSize = TextFieldAutoSize.LEFT;
			_textField.selectable = false;
			// 设置文本
			_textField.text = cmntObj.message;
			// 设置格式
			var fmt:TextFormat = new TextFormat("黑体", cmntObj.fontSize, cmntObj.color, 
				cmntObj.bold, cmntObj.italic, cmntObj.underline, null, null, null, 
				null, null, null, 2);
			_textField.setTextFormat(fmt);

			addChild(_textField);

			// 透明度
			alpha = cmntObj.alpha;

			// 设置滤镜
			switch(cmntObj.fontEffect){
				case CommentUtils.FILTER_BORDER:
					filters = [new GlowFilter(cmntObj.borderColor, 0.85, 4, 4, 3)];
					break;
				case CommentUtils.FILTER_SHADOW:
					filters = [new DropShadowFilter(cmntObj.shadowDistance, (45 * cmntObj.shadowAngle), 
						cmntObj.shadowColor, cmntObj.shadowAlpha)];
					break;
			}

			// 运动相关属性
			mode = cmntObj.mode;
			life = cmntObj.life;
			x1 = cmntObj.x1;
			y1 = cmntObj.y1;
			x2 = cmntObj.x2;
			y2 = cmntObj.y2;
			angle = cmntObj.angle;

			// 锁定标记
			locked = cmntObj.locked;

			// 显示边框
			if(cmntObj.border) {
				_textField.border = true;
				_textField.borderColor = 0x0080ff;
				// 存在边框时，宽和高各+1，保证边框显示完全
				setSize(width + 2, height + 1);
			}

			_inEff = createEffect(cmntObj.inEffect);
			_outEff = createEffect(cmntObj.outEffect);
		}
		
		/**
		 * 弹幕进入场景
		 */
		public function enter():void {
			effecting = true;
			
			visible = true;
			if(_inEff != null){
				_inEff.addEventListener(TransitionUtils.TRANSITION_IN_DONE, transitionEndHandler);
				_inEff.start();
			}
			else{
				transitionEndHandler(new Event(TransitionUtils.TRANSITION_IN_DONE));
			}
		}
		
		/**
		 * 弹幕离开场景
		 */
		public function leave():void {
			effecting = true;
			
			if(_outEff != null){
				_outEff.addEventListener(TransitionUtils.TRANSITION_OUT_DONE, transitionEndHandler);
				_outEff.start();
			}
			else{
				transitionEndHandler(new Event(TransitionUtils.TRANSITION_OUT_DONE));
			}
		}

		public function get rect():Rectangle {
			return new Rectangle(x, y, width, height);
		}

		private function createEffect(config:TransitionConfig):Transition {
			var trans:Transition = null;
			var cfgObj:Object = {
				direction: config.direction, 
				duration: config.duration / 1000, 
				easing: None.easeNone
			};

			if(_transManager == null) _transManager = new TransitionManager(this);
			switch(config.effectID){
				case CommentUtils.EFFECT_FADE:
					trans = new Fade(this, cfgObj, _transManager);
					break;
				case CommentUtils.EFFECT_IRIS:
					cfgObj.shape = config.irisShape;
					cfgObj.startPoint = 5;
					trans = new Iris(this, cfgObj, _transManager);
					break;
				case CommentUtils.EFFECT_WIPE:
					cfgObj.startPoint = config.wipeStart;
					trans = new Wipe(this, cfgObj, _transManager);
					break;
				case CommentUtils.EFFECT_BLINDS:
					cfgObj.dimension = config.blindsDim;
					cfgObj.numStrips = config.blindsNum;
					trans = new Blinds(this, cfgObj, _transManager);
					break;
				case CommentUtils.EFFECT_DISSOLVE:
					cfgObj.xSections = config.dissolveXSec;
					cfgObj.ySections = config.dissolveYSec;
					trans = new PixelDissolve(this, cfgObj, _transManager);
					break;
			}
			return trans;
		}

		private function releaseEffects():void {
			this._transManager.removeAllTransitions();
			this._transManager = null;
			this._inEff = null;
			this._outEff = null;
		}

		private function setSize(width:Number, height:Number):void {
			graphics.beginFill(0, 0);
			graphics.drawRect(0, 0, width, height);
			graphics.endFill();
		}

		protected function transitionEndHandler(e:Event):void {
			effecting = false;

			if(e.type == TransitionUtils.TRANSITION_IN_DONE){
				if(_inEff != null)
					_inEff.removeEventListener(TransitionUtils.TRANSITION_IN_DONE, transitionEndHandler);

				dispatchEvent(new CommentEvent(CommentEvent.EFFECT_END, Transition.IN));
			}
			if(e.type == TransitionUtils.TRANSITION_OUT_DONE){
				if(_outEff != null)
					_outEff.removeEventListener(TransitionUtils.TRANSITION_OUT_DONE, transitionEndHandler);
				visible = false;
				releaseEffects();

				dispatchEvent(new CommentEvent(CommentEvent.EFFECT_END, Transition.OUT));
			}
		}
	}
}